import { invoke } from '@tauri-apps/api/tauri'
import { open, save } from '@tauri-apps/api/dialog'
import { readTextFile, writeTextFile, readDir, createDir, removeFile, removeDir, renameFile, exists } from '@tauri-apps/api/fs'
import { basename, dirname, join } from '@tauri-apps/api/path'

export interface FileItem {
  name: string
  path: string
  type: 'file' | 'folder'
  expanded?: boolean
  children?: FileItem[]
  content?: string
}

export class FileService {
  private currentWorkspace: string = ''

  // 打开文件对话框
  async openFile(): Promise<{ content: string; path: string; name: string } | null> {
    try {
      const filePath = await open({
        multiple: false,
        filters: [
          {
            name: 'Markdown',
            extensions: ['md', 'markdown', 'txt']
          },
          {
            name: '所有文件',
            extensions: ['*']
          }
        ]
      })

      if (filePath && typeof filePath === 'string') {
        const content = await readTextFile(filePath)
        const name = await basename(filePath)
        return { content, path: filePath, name }
      }
      return null
    } catch (error) {
      console.error('打开文件失败:', error)
      throw new Error('打开文件失败')
    }
  }

  // 保存文件
  async saveFile(content: string, filePath?: string): Promise<string> {
    try {
      let targetPath = filePath

      if (!targetPath) {
        // 显示保存对话框
        targetPath = await save({
          filters: [
            {
              name: 'Markdown',
              extensions: ['md']
            },
            {
              name: '文本文件',
              extensions: ['txt']
            }
          ],
          defaultPath: '未命名.md'
        })
      }

      if (targetPath) {
        await writeTextFile(targetPath, content)
        return targetPath
      }
      throw new Error('未选择保存路径')
    } catch (error) {
      console.error('保存文件失败:', error)
      throw new Error('保存文件失败')
    }
  }

  // 读取目录
  async readDirectory(dirPath: string): Promise<FileItem[]> {
    try {
      const entries = await readDir(dirPath, { recursive: false })
      const items: FileItem[] = []

      for (const entry of entries) {
        const item: FileItem = {
          name: entry.name || '',
          path: entry.path,
          type: entry.children ? 'folder' : 'file',
          expanded: false
        }

        if (item.type === 'folder') {
          item.children = []
        }

        items.push(item)
      }

      // 排序：文件夹在前，文件在后
      return items.sort((a, b) => {
        if (a.type === 'folder' && b.type === 'file') return -1
        if (a.type === 'file' && b.type === 'folder') return 1
        return a.name.localeCompare(b.name)
      })
    } catch (error) {
      console.error('读取目录失败:', error)
      return []
    }
  }

  // 递归读取目录树
  async readDirectoryTree(dirPath: string, maxDepth: number = 3, currentDepth: number = 0): Promise<FileItem[]> {
    if (currentDepth >= maxDepth) return []

    try {
      const entries = await readDir(dirPath, { recursive: false })
      const items: FileItem[] = []

      for (const entry of entries) {
        const item: FileItem = {
          name: entry.name || '',
          path: entry.path,
          type: entry.children ? 'folder' : 'file',
          expanded: false
        }

        if (item.type === 'folder') {
          // 递归读取子目录
          item.children = await this.readDirectoryTree(entry.path, maxDepth, currentDepth + 1)
        }

        items.push(item)
      }

      return items.sort((a, b) => {
        if (a.type === 'folder' && b.type === 'file') return -1
        if (a.type === 'file' && b.type === 'folder') return 1
        return a.name.localeCompare(b.name)
      })
    } catch (error) {
      console.error('读取目录树失败:', error)
      return []
    }
  }

  // 读取文件内容
  async readFile(filePath: string): Promise<string> {
    try {
      return await readTextFile(filePath)
    } catch (error) {
      console.error('读取文件失败:', error)
      throw new Error('读取文件失败')
    }
  }

  // 创建新文件
  async createFile(dirPath: string, fileName: string, content: string = ''): Promise<string> {
    try {
      const filePath = await join(dirPath, fileName)
      await writeTextFile(filePath, content)
      return filePath
    } catch (error) {
      console.error('创建文件失败:', error)
      throw new Error('创建文件失败')
    }
  }

  // 创建文件夹
  async createFolder(dirPath: string, folderName: string): Promise<string> {
    try {
      const folderPath = await join(dirPath, folderName)
      await createDir(folderPath, { recursive: true })
      return folderPath
    } catch (error) {
      console.error('创建文件夹失败:', error)
      throw new Error('创建文件夹失败')
    }
  }

  // 删除文件
  async deleteFile(filePath: string): Promise<void> {
    try {
      await removeFile(filePath)
    } catch (error) {
      console.error('删除文件失败:', error)
      throw new Error('删除文件失败')
    }
  }

  // 删除文件夹
  async deleteFolder(folderPath: string): Promise<void> {
    try {
      await removeDir(folderPath, { recursive: true })
    } catch (error) {
      console.error('删除文件夹失败:', error)
      throw new Error('删除文件夹失败')
    }
  }

  // 重命名文件或文件夹
  async rename(oldPath: string, newName: string): Promise<string> {
    try {
      const dir = await dirname(oldPath)
      const newPath = await join(dir, newName)
      await renameFile(oldPath, newPath)
      return newPath
    } catch (error) {
      console.error('重命名失败:', error)
      throw new Error('重命名失败')
    }
  }

  // 检查文件是否存在
  async fileExists(filePath: string): Promise<boolean> {
    try {
      return await exists(filePath)
    } catch (error) {
      return false
    }
  }

  // 打开工作区文件夹
  async openWorkspace(): Promise<FileItem[]> {
    try {
      const dirPath = await open({
        directory: true,
        multiple: false
      })

      if (dirPath && typeof dirPath === 'string') {
        this.currentWorkspace = dirPath
        return await this.readDirectoryTree(dirPath)
      }
      return []
    } catch (error) {
      console.error('打开工作区失败:', error)
      throw new Error('打开工作区失败')
    }
  }

  // 获取当前工作区路径
  getCurrentWorkspace(): string {
    return this.currentWorkspace
  }

  // 设置当前工作区
  setCurrentWorkspace(path: string): void {
    this.currentWorkspace = path
  }

  // 刷新文件树
  async refreshFileTree(): Promise<FileItem[]> {
    if (this.currentWorkspace) {
      return await this.readDirectoryTree(this.currentWorkspace)
    }
    return []
  }

  // 搜索文件
  async searchFiles(query: string, searchPath?: string): Promise<FileItem[]> {
    const basePath = searchPath || this.currentWorkspace
    if (!basePath) return []

    try {
      const allFiles = await this.readDirectoryTree(basePath, 5)
      return this.filterFileTree(allFiles, query)
    } catch (error) {
      console.error('搜索文件失败:', error)
      return []
    }
  }

  // 过滤文件树
  private filterFileTree(items: FileItem[], query: string): FileItem[] {
    const result: FileItem[] = []
    const lowerQuery = query.toLowerCase()

    for (const item of items) {
      if (item.type === 'file' && item.name.toLowerCase().includes(lowerQuery)) {
        result.push(item)
      } else if (item.type === 'folder' && item.children) {
        const filteredChildren = this.filterFileTree(item.children, query)
        if (filteredChildren.length > 0) {
          result.push({
            ...item,
            children: filteredChildren,
            expanded: true
          })
        } else if (item.name.toLowerCase().includes(lowerQuery)) {
          result.push(item)
        }
      }
    }

    return result
  }
}

// 导出单例实例
export const fileService = new FileService()